#include <kutils.h>
#include "hardware_detection.h"
#include "display.h"
#include "pci.h"
#include "isa.h"

//FIXME: change to linked list
hw_device_t hw_devices[256];

void hw_scan()
{
	pci_scan();

	// if a PCI to ISA bridge exists then add all of the standard ISA devices:
	hw_device_t* bridge = hw_find_device(HW_DONT_CARE, HW_DONT_CARE, HW_CLASS_BRIDGE, HW_SUBCLASS_PCI_ISA);
	if(bridge)
	{
		isa_scan();	
	}
}

void hw_add_device(u8int bus_type, u16int device_id, u16int vendor_id, u8int class_code,
							u8int subclass_code, u8int prog_if, u8int revision, u8int interrupt_pin, u8int interrupt_line)
{
	s32int i = 0;
	for(i = 0; i < 256; i++)
	{
		if(!hw_devices[i].present)
		{
			hw_devices[i].present = 1;
			hw_devices[i].bus_type = bus_type;
			hw_devices[i].device_id = device_id;
			hw_devices[i].vendor_id = vendor_id;
			hw_devices[i].class_code = class_code;
			hw_devices[i].subclass_code = subclass_code;
			hw_devices[i].prog_if = prog_if;
			hw_devices[i].revision = revision;
			hw_devices[i].interrupt_pin = interrupt_pin;
			hw_devices[i].interrupt_line = interrupt_line;

#ifdef FLUIDIUM_DEBUG
			write_string("Added new device:\n");
			write_string("   Vendor: "); write_hex(vendor_id); write_string("\n");
			write_string("   Device: "); write_hex(device_id); write_string("\n");
			write_string("   Class: "); write_hex(class_code); write_string("\n");
			write_string("   Subclass: "); write_hex(subclass_code); write_string("\n\n");
#endif
			break;
		}
	}
}

hw_device_t* hw_find_device(u16int device_id, u16int vendor_id, u8int class_code, u8int subclass_code)
{
	int i = 0;
	for(i = 0; i < 255; i++)
	{
		if(!hw_devices[i].present)
			continue;

		if(device_id != HW_DONT_CARE && device_id != hw_devices[i].device_id)
			continue;

		if(vendor_id != HW_DONT_CARE && vendor_id != hw_devices[i].vendor_id)
			continue;

		if(class_code != HW_DONT_CARE && class_code != hw_devices[i].class_code)
			continue;

		if(subclass_code != HW_DONT_CARE && subclass_code != hw_devices[i].subclass_code)
			continue;

		//if we reach here it means all cases were satisfied. A match has been found.
		return (hw_device_t*)&hw_devices[i];
	}
	return 0;
}

